package com.firsteapps.mobile.android.puzzle.game;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.firsteapps.mobile.android.puzzle.Continue;
import com.firsteapps.mobile.android.puzzle.PostLoginBase;
import com.firsteapps.mobile.android.puzzle.R;
import com.firsteapps.mobile.android.puzzle.RunOut;
import com.firsteapps.mobile.android.puzzle.util.Consts;

public class GameScreen extends PostLoginBase implements MoveActionListener, PuzzleCompletedCallback {
	Context context;

	private TextView movesViewer, timeViewer;

	private Puzzle mPuzzle;
	private DrawView drawView;
	private PuzzleInfo info;
	private String loadedInfoFIleName;
	private MediaPlayer mp;
	private int mSize;
	private boolean updateTimer, runThread;
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (runThread && mPuzzle != null) {
				info = mPuzzle.getInfo();
				if (info.addElapsedTime(1000)) {
					timeViewer.setText(Helper.getElapsedTime(info.getElapsed())
							+ (info.getMaxTime() > 0 ? "/" + Helper.getElapsedTime(info.getMaxTime() * 1000) : ""));
					mPuzzle.setInfo(info);
				} else {
					runThread = false;
					Intent myIntent = new Intent(GameScreen.this, RunOut.class);
					myIntent.putExtra(Consts.INFO_RUNOUT_TYPE, Consts.RUNOUT_TIME);
					myIntent.putExtra(Consts.PUZZLE_FILE_NAME, loadedInfoFIleName);
					startActivity(myIntent);
					finish();
					overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
				}
			}
		}
	};

	@Override
	public void onPuzzleCompleted() {
		runThread = false;
		Intent myIntent = new Intent(GameScreen.this, RunOut.class);
		myIntent.putExtra(Consts.INFO_RUNOUT_TYPE, Consts.RUNOUT_NONE);
		myIntent.putExtra(Consts.PUZZLE_FILE_NAME, loadedInfoFIleName);
		myIntent.putExtra(Consts.PUZZLE_KEY, mPuzzle.getInfo());
		startActivity(myIntent);
		finish();
		overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
	}

	@Override
	public void onMovePerformed() {
		int maxMoves = mPuzzle.getInfo().getMaxMoves();
		if (maxMoves < 0)
			movesViewer.setText(mPuzzle.getInfo().getMoveCount() + "");
		else
			movesViewer.setText(mPuzzle.getInfo().getMoveCount() + "/" + maxMoves);
	}

	@Override
	public void onMoveRejected() {
		runThread = false;
		Intent myIntent = new Intent(GameScreen.this, RunOut.class);
		myIntent.putExtra(Consts.INFO_RUNOUT_TYPE, Consts.RUNOUT_MOVES);
		myIntent.putExtra(Consts.PUZZLE_FILE_NAME, loadedInfoFIleName);
		myIntent.putExtra(Consts.PUZZLE_KEY, mPuzzle.getInfo());
		startActivity(myIntent);
		finish();
		overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.game_layout);
		context = this;

		movesViewer = (TextView) findViewById(R.id.moves_viewer);
		timeViewer = (TextView) findViewById(R.id.time_viewer);

		loadedInfoFIleName = getIntent().getStringExtra(Consts.PUZZLE_KEY);
		System.out.println(loadedInfoFIleName);
		// continuePuzzle =
		// getIntent().getBooleanExtra(Consts.PUZZLE_CONTINUE_OR_NEW, false);
		info = Helper.loadCreatedPuzzle(context, loadedInfoFIleName);

		if (info == null) {
			runThread = false;
			Helper.doMessageDialog(context, "Game Screen", "Unable to load selected puzzle");
		} else {
			if (info.isCompleted()) {
				Intent myIntent = new Intent(GameScreen.this, RunOut.class);
				myIntent.putExtra(Consts.INFO_RUNOUT_TYPE, Consts.RUNOUT_NONE);
				myIntent.putExtra(Consts.PUZZLE_FILE_NAME, loadedInfoFIleName);
				startActivity(myIntent);
				finish();
				overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
			}

			movesViewer.setText(info.getMoveCount() + (info.getMaxMoves() > 0 ? "/" + info.getMaxMoves() : ""));
			timeViewer.setText(Helper.getElapsedTime(info.getElapsed())
					+ (info.getMaxTime() > 0 ? "/" + Helper.getElapsedTime(info.getMaxTime() * 1000) : ""));

			drawView = (DrawView) findViewById(R.id.puzzleView);
			mSize = info.getSize();
			drawView.setPuzzleSize(mSize);
			mPuzzle = new Puzzle(Helper.getBitmap(GameScreen.this, info.getFile()), info);
			// mPuzzle.setCreated(continuePuzzle);

			boolean[] settings = getSettings();
			drawView.setSoundsEnabled(settings[1]);
			drawView.setVibrationEnabled(settings[2]);
			drawView.setPuzzle(mPuzzle);
			drawView.setMoveListener(this);
			drawView.setPuzzleCompleted(this);
		}

		ImageView pauseGame = (ImageView) this.findViewById(R.id.gs_pause);
		pauseGame.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				updateTimer = false;
				AlertDialog dialog = new AlertDialog.Builder(GameScreen.this).setTitle("Puzzle Game")
						.setMessage("Are you sure you want to pause the game?")
						.setPositiveButton(android.R.string.ok, new android.content.DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								if (mPuzzle != null) {
									info = mPuzzle.getInfo();
									info.setTilePositions(mPuzzle.getTilePositions());
									Helper.saveOngoingPuzzle(GameScreen.this, loadedInfoFIleName, info);
								}
								Intent myIntent = new Intent(GameScreen.this, Continue.class);
								myIntent.putExtra(Consts.PUZZLE_KEY, loadedInfoFIleName);
								startActivity(myIntent);
								finish();
								overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
							}
						}).setNegativeButton(android.R.string.cancel, new android.content.DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								updateTimer = true;
								dialog.dismiss();
							}
						}).create();
				dialog.show();
			}
		});

		ImageView runoutAutosolve = (ImageView) findViewById(R.id.autosolve_puzzle);
		runoutAutosolve.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mPuzzle != null) {
					info = mPuzzle.getInfo();
					info.setTilePositions(mPuzzle.getTilePositions());
					Helper.autosolvePuzzle(GameScreen.this, loadedInfoFIleName, info);
				}
			}
		});
	}


	@Override
	protected void onResume() {
		super.onResume();

		mp = MediaPlayer.create(this, R.raw.move);
		drawView.setMp(mp);

		if (info.getTilePositions() == null) {
			if (!info.increaseAttemptCount()) {
				runThread = false;
				Intent myIntent = new Intent(GameScreen.this, RunOut.class);
				myIntent.putExtra(Consts.INFO_RUNOUT_TYPE, Consts.RUNOUT_ATTEMPTS);
				myIntent.putExtra(Consts.PUZZLE_FILE_NAME, loadedInfoFIleName);
				startActivity(myIntent);
				finish();
				overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
			} else {
				Thread registerIncompletePuzzle = new Thread(new Runnable() {
					@Override
					public void run() {
						Helper.registerPuzzle(GameScreen.this, getWorkingDirectory() + Consts.FOLDER_NAME_INCOMPLETE_PUZZLES, loadedInfoFIleName);
					}
				});
				registerIncompletePuzzle.start();
			}
		}

		runThread = true;
		updateTimer = true;

		Thread background = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					while (runThread) {
						if (updateTimer) {
							Thread.sleep(1000);
							handler.sendMessage(new Message());
						}
					}
				} catch (Exception e) {
					Log.v("Error", e.toString());
				}
			}
		});

		background.start();
	}

	@Override
	protected void onPause() {
		if (mp != null) {
			mp.stop();
			mp.release();
			mp = null;
		}

		updateTimer = false;

		if (mPuzzle != null) {
			info = mPuzzle.getInfo();
			info.setTilePositions(mPuzzle.getTilePositions());
			Helper.saveOngoingPuzzle(this, loadedInfoFIleName, info);
		}
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		Log.d("MainMenuActivity", "onSaveInstanceState");
		updateTimer = false;
		if (mPuzzle != null) {
			info = mPuzzle.getInfo();
			info.setTilePositions(mPuzzle.getTilePositions());
			outState.putSerializable(Consts.PUZZLE_KEY, info);
		}
		super.onSaveInstanceState(outState);
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		info = (PuzzleInfo) savedInstanceState.getSerializable(Consts.PUZZLE_KEY);
		mSize = info.getSize();
		movesViewer.setText(info.getMoveCount() + (info.getMaxMoves() > 0 ? "/" + info.getMaxMoves() : ""));
		timeViewer.setText(Helper.getElapsedTime(info.getElapsed())
				+ (info.getMaxTime() > 0 ? "/" + Helper.getElapsedTime(info.getMaxTime() * 1000) : ""));

		mPuzzle = new Puzzle(Helper.getBitmap(GameScreen.this, info.getFile()), info);
		drawView.setPuzzle(mPuzzle);
		drawView.setPuzzleSize(mSize);
		drawView.setMp(mp);
		super.onRestoreInstanceState(savedInstanceState);
	}
}